#include "StdAfx.h"

Mesh::Mesh()
{
	m_mesh = 0;
}

void Mesh::Scale(float x, float y, float z)
{
}

bool Mesh::Load(void* pVertices, VertexFMT format, ui32 nVertices, ui32 nPrims, WORD* pIndices, ui32 numIndices)
{
	if(!pVertices)
		return false;
	HRESULT hRes = D3D_OK;
	ui32 len = 0;
	switch(format)
	{
	case VERTEX3F:
		len = nVertices * 12;
		break;
	case VERTEX3FC:
		len = nVertices * 16;
		break;
	case VERTEX3FCT:
		len = nVertices * 24;
		break;
	case VERTEX3FT:
		len = nVertices * 20;
		break;
	case VERTEX3FRHW:
		len = nVertices * 16;
		break;
	case VERTEX3FT2:
		len = nVertices * 28;
		break;
	case VERTEX3FNT2:
		len = nVertices * 40;
		break;
	case ::Vertex3FCNT2::FVF:
		len = nVertices * Vertex3FCNT2::stride;
		break;
	};

	if(!len)
		return false;

	hRes = D3DXCreateMeshFVF(nPrims, nVertices, D3DXMESH_MANAGED, (DWORD)format, sD3D, &m_mesh);
	if(FAILED(hRes))
	{
		Log::Print("Could not create mesh: %X\n", HRESULT_CODE(hRes));
		return false;
	}
	VOID* pOut = 0;
	m_mesh->LockVertexBuffer(0, &pOut);
	memcpy(pOut, pVertices, len);
	m_mesh->UnlockVertexBuffer();
	if(!pIndices)
	{
		WORD* indices = new WORD[nPrims * 3];
		for(ui32 i = 0; i < nPrims * 3; ++i)
			indices[i] = i;
		m_mesh->LockIndexBuffer(0, &pOut);
		memcpy(pOut, indices, 3 * nPrims * sizeof(WORD));
		m_mesh->UnlockIndexBuffer();
		delete [] indices;
	}
	else
	{
		m_mesh->LockIndexBuffer(0, &pOut);
		if(numIndices)
			memcpy(pOut, pIndices, numIndices * sizeof(WORD));
		else
			memcpy(pOut, pIndices, nPrims * 3 * sizeof(WORD));
		m_mesh->UnlockIndexBuffer();
	}
	return true;
}

void Mesh::Draw()
{
	if(!m_mesh)
		return;
	m_lock.Acquire();
	m_mesh->DrawSubset(0);
	m_lock.Release();
}

bool Mesh::Intersect(const D3DXVECTOR3& pt1, const D3DXVECTOR3& dir, FLOAT& inter)
{
	if(!m_mesh)
		return false;
	BOOL fHit = FALSE;
	D3DXIntersect(m_mesh, &pt1, &dir, &fHit, 0, 0, 0, &inter, 0, 0);
	return fHit > 0;
}

Mesh::~Mesh()
{
	if(m_mesh)
	{
		while(m_mesh->Release() > 0);
	}
}